import AsyncStorage from '@react-native-community/async-storage';
import GitHubTrending from 'GitHubTrending';

export const FLAG_STORAGE = {flag_popular: 'popular', flag_trending: 'trending'};

export default class DataStore {

  /**
   * 获取数据
   * @param url
   * @returns {Promise<any>}
   */
  fetchData(url, flag) {
    return new Promise((resolve, reject) => {
      this.fetchLocalData(url) // 优先从本地获取数据
        .then(wrapData => {
          if (wrapData && DataStore.checkTimestamp(wrapData.timestamp)) { // 本地数据存在且未过期
            resolve(wrapData)
          } else { // 本地数据不存在或已过期，从网络获取数据
            this.fetchNetData(url, flag)
              .then(wrapData => resolve(wrapData))
              .catch(error => reject(error));
          }
        })
        .catch(() => { // 获取本地数据失败时，从网络获取数据
          this.fetchNetData(url, flag)
            .then(wrapData => resolve(wrapData))
            .catch(error => reject(error));
        })
    })
  }

  /**
   * 检查数据是否过期(静态方法)
   * @param timestamp
   * @returns {boolean}
   */
  static checkTimestamp(timestamp) {
    const currentDate = new Date();
    const targetDate = new Date(timestamp);
    // 年，月，日是否一致
    if (currentDate.getFullYear() !== targetDate.getFullYear()) return false;
    if (currentDate.getMonth() !== targetDate.getMonth()) return false;
    if (currentDate.getDate() !== targetDate.getDate()) return false;
    // 超过4个小时过期
    if (currentDate.getHours() - targetDate.getHours() > 4) return false;
    return true;
  }

  /**
   * 获取本地数据
   * @param url
   * @returns {Promise<any>}
   */
  fetchLocalData(url) {
    return new Promise((resolve, reject) => {
      AsyncStorage.getItem(url, (error, result) => {
        if (!error) {
          try {
            resolve(JSON.parse(result)); // 解析为JSON格式
          } catch (e) {
            reject(e);
            console.log(e);
          }
        } else {
          reject(error);
          console.log(error)
        }
      })
    });
  }

  /**
   * 获取网络数据
   * @param url
   * @returns {Promise<any>}
   */
  fetchNetData(url, flag) {
    return new Promise((resolve, reject) => {
      if (flag === FLAG_STORAGE.flag_popular) { // 如果为Popular模块数据请求
        fetch(url)
          .then(response => {
            if (response.ok) {
              return response.json();
            }
            throw new Error('Network response was not ok');
          })
          .then(responseJson => {
            this.saveData(url, responseJson); // 将数据本地存储
            resolve(this._wrapData(responseJson)); // 返回添加时间戳的数据
          })
          .catch(error => {
            reject(error);
          })
      } else { // 如果为Trending模块数据请求
        const gitHubTrending = new GitHubTrending();
        gitHubTrending.fetchTrending(url)
          .then(items => {
            if (!items) {
              throw new Error('response is null')
            }
            this.saveData(url, items);
            resolve(this._wrapData(items));
          })
          .catch(error => {
            reject(error);
          })
      }
    });
  }

  /**
   * 数据本地存储
   * @param url
   * @param data
   * @param callback
   */
  saveData(url, data) {
    // 将数据转为字符串格式进行存储
    AsyncStorage.setItem(url, JSON.stringify(this._wrapData(data)));
  }

  /**
   * 给数据添加时间戳(以便读取时判断是否过期)
   * @param data
   * @returns {{data: *, timestamp: number}}
   * @private
   */
  _wrapData(data) {
    return {data: data, timestamp: new Date().getTime()};
  }

}